{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"https://raw.githubusercontent.com/Qiskit/qiskit-tutorials/master/images/qiskit-heading.png\" alt=\"Note: In order for images to show up in this jupyter notebook you need to select File => Trusted Notebook\" width=\"500 px\" align=\"left\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "3ZyGwuu2THJe"
   },
   "source": [
    "# Quantum Cryptography: Quantum Key Distribution\n",
    "\n",
    "The latest version of this notebook is available on https://github.com/qiskit/qiskit-tutorial.\n",
    "\n",
    "***\n",
    "### Contributors:\n",
    "A.J. Rasmusson, Richard Barney\n",
    "### Qiskit Package Versions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'qiskit': '0.10.3',\n",
       " 'qiskit-terra': '0.8.1',\n",
       " 'qiskit-ignis': '0.1.1',\n",
       " 'qiskit-aer': '0.2.1',\n",
       " 'qiskit-ibmq-provider': '0.2.2',\n",
       " 'qiskit-aqua': '0.5.1'}"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import qiskit\n",
    "qiskit.__qiskit_version__\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Have you ever wanted to send a super secret message to a friend? Then you need a key to encrypt your message, and your friend needs the same key to decrypt your message. But, how do you send a super secret key to your friend without your eavesdropping enemies finding out what it is? Businesses and governments face this problem every day. People are always innovating new ways to intercept personal data or other sensitive information. Ideally, we'd like to find a way to share information that cannot be intercepted. [Quantum key distribution](https://en.wikipedia.org/wiki/Quantum_key_distribution) (QKD) was created as a solution to this problem. In this tutorial, you'll learn about and implement a version of the [BB84 QKD protocol](https://en.wikipedia.org/wiki/BB84), developed by Bennet and Brassard, to generate a secure, [one-time pad](https://en.wikipedia.org/wiki/One-time_pad) encryption key.\n",
    "\n",
    "Quantum key distribution is all about making the right information publicly known at the right times (and keeping the secret information secret). This tutorial will take you through a quantum key distribution between you (Alice) and your friend Bob. After you get a feel for the ropes by sending your first encrypted message to Bob, we'll introduce Eve--your eavesdropping enemy. You'll learn how to detect Eve's presence and thus prevent her from intercepting your super secret key and decrypting your messages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "T3qQV_nqTHJf"
   },
   "outputs": [],
   "source": [
    "#other useful packages\n",
    "import math\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "\n",
    "# Import Qiskit\n",
    "from qiskit import BasicAer, execute\n",
    "from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "c2SrYcAzWvr2"
   },
   "source": [
    "## Part 1: Encrypting and Decrypting a Message"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "ISN-rAsOTHJi"
   },
   "source": [
    "### Pick Your Super Secret Message\n",
    "The super secret message you want to send must be the same or less than the length of the super secret key.\n",
    "\n",
    "If the key is shorter than the message, you will be forced to use parts of the key more than once. This may allow your lurking enemies to pick up a pattern in your encrypted message and possibly decrypt it. (As you'll see later on, we need to start out with a key at least double the number of characters used in your message. For now, don't worry about those details, pick your message! For this tutorial, we picked the initial key to be 3x greater--just to be safe.) Enter your message on the line below which reads \"mes = \"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     },
     "base_uri": "https://localhost:8080/",
     "height": 51,
     "output_extras": [
      {
       "item_id": 1
      }
     ]
    },
    "colab_type": "code",
    "executionInfo": {
     "elapsed": 318,
     "status": "ok",
     "timestamp": 1522270875378,
     "user": {
      "displayName": "Aj Rasmusson",
      "photoUrl": "//lh5.googleusercontent.com/-Ny7-iz7VJ9o/AAAAAAAAAAI/AAAAAAAAEe0/IgVrdTnsS7Y/s50-c-k-no/photo.jpg",
      "userId": "109891151268866993124"
     },
     "user_tz": 360
    },
    "id": "764bfF7mfd6e",
    "outputId": "a08f86b9-407c-4383-d4a0-54e4e855b2d6"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Your super secret message:  hello world\n",
      "Initial key length:  33\n"
     ]
    }
   ],
   "source": [
    "#Super secret message\n",
    "mes = 'hello world'\n",
    "print('Your super secret message: ',mes)\n",
    "\n",
    "#initial size of key\n",
    "n = len(mes)*3\n",
    "\n",
    "#break up message into smaller parts if length > 10\n",
    "nlist = []\n",
    "for i in range(int(n/10)):\n",
    "    nlist.append(10)\n",
    "if n%10 != 0:\n",
    "    nlist.append(n%10)\n",
    "\n",
    "print('Initial key length: ',n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "j0Y9ZghAWzqk"
   },
   "source": [
    "### The Big Picture\n",
    "Now that you (Alice) have the key, here's the big question: how are we going to get your key to Bob without eavesdroppers intercepting it? Quantum key distribution! Here are the steps and big picture (the effects of eavesdropping will be discussed later on):\n",
    "1. You (Alice) generate a random string--the key you wish to give to Bob.\n",
    "2. You (Alice) convert your string bits into corresponding qubits.\n",
    "3. You (Alice) send those qubits to Bob, BUT! you randomly rotate some into a superposition. This effectively turns your key into random noise. (This is good because your lurking enemies might measure your qubits.)\n",
    "4. Bob receives yours qubits AND randomly rotates some qubits in the opposite direction before measuring.\n",
    "5. Alice and Bob publicly share which qubits they rotated. When they both did the same thing (either both did nothing or both rotated), they know the original key bit value made it to Bob! (Overall, you can see that only some of the bits from Alice's original key should make it.)\n",
    "6. Alice and Bob create their keys. Alice modifies her original key by keeping only the bits that she knows made it to Bob. Bob does the same.\n",
    "\n",
    "Alice and Bob now have matching keys! They can now use this key to encrypt and decrypt their messages.\n",
    "\n",
    "<img src='QKDnoEve.png'>\n",
    "Here we see Alice sending the initial key to Bob. She sends her qubits and rotates them based on her rotation string. Bob rotates the incoming qubits based on his rotation string and measures the qubits."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "xmDNctysTHJj"
   },
   "source": [
    "### Step 1: Alice Generates a Random Key\n",
    "You and your friend need a super secret key so you can encrypt your message and your friend can decrypt it. Let's make a key--a pure random key.\n",
    "\n",
    "To make a purely random string, we'll use quantum superposition. A qubit in the xy-plane of the [Bloch sphere](https://quantumexperience.ng.bluemix.net/qx/tutorial?sectionId=beginners-guide&page=004-The_Weird_and_Wonderful_World_of_the_Qubit~2F001-The_Weird_and_Wonderful_World_of_the_Qubit) is in a 50-50 [superposition](https://quantumexperience.ng.bluemix.net/qx/tutorial?sectionId=beginners-guide&page=005-Single-Qubit_Gates~2F002-Creating_superposition); 50% of the time it'll be measured as 0, and 50% of the time it'll be measured as 1. We have Alice prepare several qubits like this and measure them to generate a purely random string of 1s and 0s."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "F1eTyd6XTHJk"
   },
   "outputs": [],
   "source": [
    "# Make random strings of length string_length\n",
    "\n",
    "def randomStringGen(string_length):\n",
    "    #output variables used to access quantum computer results at the end of the function\n",
    "    output_list = []\n",
    "    output = ''\n",
    "    \n",
    "    #start up your quantum circuit information\n",
    "    backend = BasicAer.get_backend('qasm_simulator')  \n",
    "    circuits = ['rs']\n",
    "    \n",
    "    #run circuit in batches of 10 qubits for fastest results. The results\n",
    "    #from each run will be appended and then clipped down to the right n size.\n",
    "    n = string_length\n",
    "    temp_n = 10\n",
    "    temp_output = ''\n",
    "    for i in range(math.ceil(n/temp_n)):\n",
    "        #initialize quantum registers for circuit\n",
    "        q = QuantumRegister(temp_n, name='q')\n",
    "        c = ClassicalRegister(temp_n, name='c')\n",
    "        rs = QuantumCircuit(q, c, name='rs')\n",
    "            \n",
    "        #create temp_n number of qubits all in superpositions\n",
    "        for i in range(temp_n):\n",
    "            rs.h(q[i]) #the .h gate is the Hadamard gate that makes superpositions\n",
    "            rs.measure(q[i],c[i])\n",
    "\n",
    "        #execute circuit and extract 0s and 1s from key\n",
    "        result = execute(rs, backend, shots=1).result()\n",
    "        counts = result.get_counts(rs)\n",
    "        result_key = list(result.get_counts(rs).keys())\n",
    "        temp_output = result_key[0]\n",
    "        output += temp_output\n",
    "        \n",
    "    #return output clipped to size of desired string length\n",
    "    return output[:n]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "ESW3Iz0yXCLn"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Initial key:  011010011101110010101101011011011\n"
     ]
    }
   ],
   "source": [
    "key = randomStringGen(n)\n",
    "print('Initial key: ',key)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "92XYZDkEgCLg"
   },
   "source": [
    "### Steps 2-4: Send Alice's Qubits to Bob\n",
    "Alice turns her key bits into corresponding qubit states. If a bit is a 0 she will prepare a qubit on the negative z axis. If the bit is a 1 she will prepare a qubit on the positive z axis. Next, if Alice has a 1 in her rotate string, she rotates her key qubit with a [Hadamard](https://quantumexperience.ng.bluemix.net/qx/tutorial?sectionId=beginners-guide&page=005-Single-Qubit_Gates~2F002-Creating_superposition) gate. She then sends the qubit to Bob. If Bob has a 1 in his rotate string, he rotates the incoming qubit in the opposite direction with a Hadamard gate. Bob then measures the state of the qubit and records the result. The quantum circuit below executes each of these steps."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "PUiuyPV7THJn"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Alice's rotation string: 100111000100100010111001010010000\n",
      "Bob's rotation string:   000111101110110100011101000111010\n",
      "Bob's results:  111010010111100000101101011111001\n"
     ]
    }
   ],
   "source": [
    "#generate random rotation strings for Alice and Bob\n",
    "Alice_rotate = randomStringGen(n)\n",
    "Bob_rotate = randomStringGen(n)\n",
    "print(\"Alice's rotation string:\",Alice_rotate)\n",
    "print(\"Bob's rotation string:  \",Bob_rotate)\n",
    "\n",
    "#start up your quantum program\n",
    "backend = BasicAer.get_backend('qasm_simulator')  \n",
    "shots = 1\n",
    "circuits = ['send_over']\n",
    "Bob_result = ''\n",
    "\n",
    "for ind,l in enumerate(nlist):\n",
    "    #define temp variables used in breaking up quantum program if message length > 10\n",
    "    if l < 10:\n",
    "        key_temp = key[10*ind:10*ind+l]\n",
    "        Ar_temp = Alice_rotate[10*ind:10*ind+l]\n",
    "        Br_temp = Bob_rotate[10*ind:10*ind+l]\n",
    "    else:\n",
    "        key_temp = key[l*ind:l*(ind+1)]\n",
    "        Ar_temp = Alice_rotate[l*ind:l*(ind+1)]\n",
    "        Br_temp = Bob_rotate[l*ind:l*(ind+1)]\n",
    "    \n",
    "    #start up the rest of your quantum circuit information\n",
    "    q = QuantumRegister(l, name='q')\n",
    "    c = ClassicalRegister(l, name='c')\n",
    "    send_over = QuantumCircuit(q, c, name='send_over')\n",
    "    \n",
    "    #prepare qubits based on key; add Hadamard gates based on Alice's and Bob's\n",
    "    #rotation strings\n",
    "    for i,j,k,n in zip(key_temp,Ar_temp,Br_temp,range(0,len(key_temp))):\n",
    "        i = int(i)\n",
    "        j = int(j)\n",
    "        k = int(k)\n",
    "        if i > 0:\n",
    "            send_over.x(q[n])\n",
    "        #Look at Alice's rotation string\n",
    "        if j > 0:\n",
    "            send_over.h(q[n])\n",
    "        #Look at Bob's rotation string\n",
    "        if k > 0:\n",
    "            send_over.h(q[n])\n",
    "        send_over.measure(q[n],c[n])\n",
    "\n",
    "    #execute quantum circuit\n",
    "    result_so = execute([send_over], backend, shots=shots).result()\n",
    "    counts_so = result_so.get_counts(send_over)\n",
    "    result_key_so = list(result_so.get_counts(send_over).keys())\n",
    "    Bob_result += result_key_so[0][::-1]\n",
    "    \n",
    "print(\"Bob's results: \", Bob_result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "nAROLS7tTHJp"
   },
   "source": [
    "### Steps 5-6: Compare Rotation Strings and Make Keys\n",
    "Alice and Bob can now generate a secret quantum encryption key. First, they publicly share their rotation strings. If a bit in Alice's rotation string is the same as the corresponding bit in Bob's they know that Bob's result is the same as what Alice sent. They keep these bits to form the new key. (Alice based on her original key and Bob based on his measured results)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "SzpzVFZcTHJq"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Alice's key: 11010111100010101101\n",
      "Bob's key:   11010111100010101101\n"
     ]
    }
   ],
   "source": [
    "def makeKey(rotation1,rotation2,results):\n",
    "    key = ''\n",
    "    count = 0\n",
    "    for i,j in zip(rotation1,rotation2):\n",
    "        if i == j:\n",
    "            key += results[count]\n",
    "        count += 1\n",
    "    return key\n",
    "  \n",
    "Akey = makeKey(Bob_rotate,Alice_rotate,key)\n",
    "Bkey = makeKey(Bob_rotate,Alice_rotate,Bob_result)\n",
    "\n",
    "print(\"Alice's key:\",Akey)\n",
    "print(\"Bob's key:  \",Bkey)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "kgtn-jXxTHJs"
   },
   "source": [
    "### Pause\n",
    "We see that using only the public knowledge of Bob's and Alice's rotation strings, Alice and Bob can create the same identical key based on Alice's initial random key and Bob's results. Wow!! :D\n",
    "\n",
    "<strong>If Alice's and Bob's key length is less than the message</strong>, the encryption is compromised. If this is the case for you, rerun all the cells above and see if you get a longer key. (We set the initial key length to 3x the message length to avoid this, but it's still possible.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "o6sBB8Fdha9Z"
   },
   "source": [
    "### Encrypt (and decrypt) using quantum key\n",
    "We can now use our super secret key to encrypt and decrypt messages!! (of length less than the key). Note: the below \"encryption\" method is not powerful and should not be used for anything you want secure; it's just for fun. In real life, the super secret key you made and shared with Bob would be used in a much more sophisticated encryption algorithm."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "U2dl6qRHhXrD"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "encoded message:   ÊÇÌÎÏÙÑÔÌÄ\n",
      "recovered message: hello world\n"
     ]
    }
   ],
   "source": [
    "#make key same length has message\n",
    "shortened_Akey = Akey[:len(mes)]\n",
    "encoded_m=''\n",
    "\n",
    "#encrypt message mes using encryption key final_key\n",
    "for m,k in zip(mes,shortened_Akey):\n",
    "    encoded_c = chr(ord(m) + 2*ord(k) % 256)\n",
    "    encoded_m += encoded_c\n",
    "print('encoded message:  ',encoded_m)\n",
    "\n",
    "#make key same length has message\n",
    "shortened_Bkey = Bkey[:len(mes)]\n",
    "\n",
    "#decrypt message mes using encryption key final_key\n",
    "result = ''\n",
    "for m,k in zip(encoded_m,shortened_Bkey):\n",
    "    encoded_c = chr(ord(m) - 2*ord(k) % 256)\n",
    "    result += encoded_c\n",
    "print('recovered message:',result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "8oCyXZdDTHJv"
   },
   "source": [
    "# Part 2: Eve the Eavesdropper\n",
    "What if someone  is eavesdropping on Alice and Bob's line of communication? This process of random string making and rotations using quantum mechanics is only useful if it's robust against eavesdroppers.\n",
    "\n",
    "Eve is your lurking enemy. She eavesdrops by intercepting your transmission to Bob. To be sneaky, Eve must send on the intercepted transmission--otherwise Bob will never receive anything and know that something is wrong!\n",
    "\n",
    "Let's explain further why Eve can be detected. If Eve intercepts a qubit from Alice, she will not know if Alice rotated its state or not. Eve can only measure a 0 or 1. And she can't measure the qubit and then send the same qubit on, because her measurement will destroy the quantum state. Consequently, Eve doesn't know when or when not to rotate to recreate Alice's original qubit. She may as well send on qubits that have not been rotated, hoping to get the rotation right 50% of the time. After she sends these qubits to Bob, Alice and Bob can compare select parts of their keys to see if they have discrepancies in places they should not.\n",
    "\n",
    "The scheme goes as follows:\n",
    "1. Alice sends her qubit transmission Bob--but Eve measures the results\n",
    "2. To avoid suspicion, Eve prepares qubits corresponding to the bits she measured and sends them to Bob.\n",
    "3. Bob and Alice make their keys like normal\n",
    "4. Alice and Bob randomly select the same parts of their keys to share publicly\n",
    "5. If the selected part of the keys don't match, they know Eve was eavesdropping\n",
    "6. If the selected part of the keys DO match, they can be confident Eve wasn't eavesdropping\n",
    "7. They throw away the part of the key they made public and encrypt and decrypt super secret messages with the portion of the key they have left.\n",
    "\n",
    "<img src=\"QKD.png\">\n",
    "Here we see Alice sending her qubits, rotationing them based on her rotation string, and Eve intercepting the transmittion. Eve then sending her results onto Bob who--like normal--rotates and measures the qubits."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "9EpsXR4jYaB3"
   },
   "source": [
    "### Step 1: Eve intercepts Alice's transmission\n",
    "\n",
    "The code below has Alice sending her qubits and Eve intercepting them. It then displays the results of Eve's measurements."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "qNwOqHMHTHJw"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Eve's results:  011011011101110000101101001011011\n"
     ]
    }
   ],
   "source": [
    "#start up your quantum program\n",
    "backend = BasicAer.get_backend('qasm_simulator')  \n",
    "shots = 1\n",
    "circuits = ['Eve']\n",
    "\n",
    "Eve_result = ''\n",
    "for ind,l in enumerate(nlist):\n",
    "    #define temp variables used in breaking up quantum program if message length > 10\n",
    "    if l < 10:\n",
    "        key_temp = key[10*ind:10*ind+l]\n",
    "        Ar_temp = Alice_rotate[10*ind:10*ind+l]\n",
    "    else:\n",
    "        key_temp = key[l*ind:l*(ind+1)]\n",
    "        Ar_temp = Alice_rotate[l*ind:l*(ind+1)]\n",
    "    \n",
    "    #start up the rest of your quantum circuit information\n",
    "    q = QuantumRegister(l, name='q')\n",
    "    c = ClassicalRegister(l, name='c')\n",
    "    Eve = QuantumCircuit(q, c, name='Eve')\n",
    "    \n",
    "    #prepare qubits based on key; add Hadamard gates based on Alice's and Bob's\n",
    "    #rotation strings\n",
    "    for i,j,n in zip(key_temp,Ar_temp,range(0,len(key_temp))):\n",
    "        i = int(i)\n",
    "        j = int(j)\n",
    "        if i > 0:\n",
    "            Eve.x(q[n])\n",
    "        if j > 0:\n",
    "            Eve.h(q[n])\n",
    "        Eve.measure(q[n],c[n])\n",
    "    \n",
    "    #execute\n",
    "    result_eve = execute(Eve, backend, shots=shots).result()\n",
    "    counts_eve = result_eve.get_counts()\n",
    "    result_key_eve = list(result_eve.get_counts().keys())\n",
    "    Eve_result += result_key_eve[0][::-1]\n",
    "\n",
    "print(\"Eve's results: \", Eve_result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "MZ760LVOTHJy"
   },
   "source": [
    "### Step 2: Eve deceives Bob\n",
    "Eve sends her measured qubits on to Bob to deceive him! Since she doesn't know which of the qubits she measured were in a superposition or not, she doesn't even know whether to send the exact values she measured or opposite values. In the end, sending on the exact values is just as good a deception as mixing them up again."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "oqC-K-LxTHJy"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Bob's previous results (w/o Eve): 111010010111100000101101011111001\n",
      "Bob's results from Eve:\t\t  011110110101000100111101001010011\n"
     ]
    }
   ],
   "source": [
    "#start up your quantum program\n",
    "backend = BasicAer.get_backend('qasm_simulator')  \n",
    "shots = 1\n",
    "circuits = ['Eve2']\n",
    "\n",
    "Bob_badresult = ''\n",
    "for ind,l in enumerate(nlist):\n",
    "    #define temp variables used in breaking up quantum program if message length > 10\n",
    "    if l < 10:\n",
    "        key_temp = key[10*ind:10*ind+l]\n",
    "        Eve_temp = Eve_result[10*ind:10*ind+l]\n",
    "        Br_temp = Bob_rotate[10*ind:10*ind+l]\n",
    "    else:\n",
    "        key_temp = key[l*ind:l*(ind+1)]\n",
    "        Eve_temp = Eve_result[l*ind:l*(ind+1)]\n",
    "        Br_temp = Bob_rotate[l*ind:l*(ind+1)]\n",
    "    \n",
    "    #start up the rest of your quantum circuit information\n",
    "    q = QuantumRegister(l, name='q')\n",
    "    c = ClassicalRegister(l, name='c')\n",
    "    Eve2 = QuantumCircuit(q , c, name='Eve2')\n",
    "    \n",
    "    #prepare qubits\n",
    "    for i,j,n in zip(Eve_temp,Br_temp,range(0,len(key_temp))):\n",
    "        i = int(i)\n",
    "        j = int(j)\n",
    "        if i > 0:\n",
    "            Eve2.x(q[n])\n",
    "        if j > 0:\n",
    "            Eve2.h(q[n])\n",
    "        Eve2.measure(q[n],c[n])\n",
    "    \n",
    "    #execute\n",
    "    result_eve = execute(Eve2, backend, shots=shots).result()\n",
    "    counts_eve = result_eve.get_counts()\n",
    "    result_key_eve = list(result_eve.get_counts().keys())\n",
    "    Bob_badresult += result_key_eve[0][::-1]\n",
    "    \n",
    "print(\"Bob's previous results (w/o Eve):\",Bob_result)\n",
    "print(\"Bob's results from Eve:\\t\\t \",Bob_badresult)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "iDxhbKkwf8FV"
   },
   "source": [
    "### Step 4: Spot Check\n",
    "Alice and Bob know Eve is lurking out there. They decide to pick a few random values from their individual keys and compare with each other. This requires making these subsections of their keys public (so the other can see them). If any of the values in their keys are different, they know Eve's eavesdropping messed up the superposition Alice originally created! If they find all the values are identical, they can be reasonably confident that Eve wasn't eavesdropping. Of course, making some random key values known to the public will require them to remove those values from their keys because those parts are no longer super secret. Also, Alice and Bob need to make sure they are sharing corresponding values from their respective keys.\n",
    "\n",
    "Let's make a check key. If the randomly generated check key is a one, Alice and Bob will compare that part of their keys with each other (aka make publicly known)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "GECxwnVZgsp-"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Alice's key:    11010111100010101101\n",
      "Bob's key:      11110111000110101101\n",
      "spots to check: 01101101111010011111\n"
     ]
    }
   ],
   "source": [
    "#make keys for Alice and Bob\n",
    "Akey = makeKey(Bob_rotate,Alice_rotate,key)\n",
    "Bkey = makeKey(Bob_rotate,Alice_rotate,Bob_badresult)\n",
    "print(\"Alice's key:   \",Akey)\n",
    "print(\"Bob's key:     \",Bkey)\n",
    "\n",
    "check_key = randomStringGen(len(Akey))\n",
    "print('spots to check:',check_key)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "xnc9qJqAg0bC"
   },
   "source": [
    "### Steps 5-7: Compare strings and detect Eve\n",
    "Alice and Bob compare the subsections of their keys. If they notice any discrepancy, they know that Eve was trying to intercept their message. They create new keys by throwing away the parts they shared publicly. It's possible that by throwing these parts away, they will not have a key long enough to encrypt the message and they will have to try again."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "colab": {
     "autoexec": {
      "startup": false,
      "wait_interval": 0
     }
    },
    "colab_type": "code",
    "id": "gNZhVcCcgxx_"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "subset of Alice's key: 10011100101101\n",
      "subset of Bob's key:   11011000101101\n",
      "Eve detected!\n"
     ]
    }
   ],
   "source": [
    "#find which values in rotation string were used to make the key\n",
    "Alice_keyrotate = makeKey(Bob_rotate,Alice_rotate,Alice_rotate)\n",
    "Bob_keyrotate = makeKey(Bob_rotate,Alice_rotate,Bob_rotate)\n",
    "\n",
    "# Detect Eve's interference\n",
    "#extract a subset of Alice's key\n",
    "sub_Akey = ''\n",
    "sub_Arotate = ''\n",
    "count = 0\n",
    "for i,j in zip(Alice_rotate,Akey):\n",
    "    if int(check_key[count]) == 1:\n",
    "        sub_Akey += Akey[count]\n",
    "        sub_Arotate += Alice_keyrotate[count]\n",
    "    count += 1\n",
    "\n",
    "#extract a subset of Bob's key\n",
    "sub_Bkey = ''\n",
    "sub_Brotate = ''\n",
    "count = 0\n",
    "for i,j in zip(Bob_rotate,Bkey):\n",
    "    if int(check_key[count]) == 1:\n",
    "        sub_Bkey += Bkey[count]\n",
    "        sub_Brotate += Bob_keyrotate[count]\n",
    "    count += 1\n",
    "print(\"subset of Alice's key:\",sub_Akey)\n",
    "print(\"subset of Bob's key:  \",sub_Bkey)\n",
    "\n",
    "#compare Alice and Bob's key subsets\n",
    "secure = True\n",
    "for i,j in zip(sub_Akey,sub_Bkey):\n",
    "    if i == j:\n",
    "        secure = True\n",
    "    else:\n",
    "        secure = False\n",
    "        break;\n",
    "if not secure:\n",
    "    print('Eve detected!')\n",
    "else:\n",
    "    print('Eve escaped detection!')\n",
    "\n",
    "#sub_Akey and sub_Bkey are public knowledge now, so we remove them from Akey and Bkey\n",
    "if secure:\n",
    "    new_Akey = ''\n",
    "    new_Bkey = ''\n",
    "    for index,i in enumerate(check_key):\n",
    "        if int(i) == 0:\n",
    "            new_Akey += Akey[index]\n",
    "            new_Bkey += Bkey[index]\n",
    "    print('new A and B keys: ',new_Akey,new_Bkey)\n",
    "    if(len(mes)>len(new_Akey)):\n",
    "        print('Your new key is not long enough.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Probability of Detecting Eve\n",
    "The longer the key, the more likely you will detect Eve. In fact, the [probability](hhttps://en.wikipedia.org/wiki/Quantum_key_distribution#Intercept_and_resend) goes up as a function of $1 - (3/4)^n$ where n is the number of bits Alice and Bob compare in their spot check. So, the longer the key, the more bits you can use to compare and the more likely you will detect Eve."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#!!! you may need to execute this cell twice in order to see the output due to an problem with matplotlib\n",
    "x = np.arange(0., 30.0)\n",
    "y = 1-(3/4)**x\n",
    "plt.plot(y)\n",
    "plt.title('Probablity of detecting Eve')\n",
    "plt.xlabel('# of key bits compared')\n",
    "plt.ylabel('Probablity of detecting Eve')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "collapsed_sections": [],
   "default_view": {},
   "name": "Quantum Cryptography.ipynb",
   "provenance": [],
   "version": "0.3.2",
   "views": {}
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
